package com.code.generator;


import com.google.common.io.Files;
import com.code.generator.model.GeneratorConfiguration;
import com.code.generator.model.TableInfo;
import com.code.util.StringUtils;
import com.code.util.TransformUtils;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

public abstract class AbstractGenerator {
    public AbstractGenerator() {
    }

    protected void saveUserCustomConfig(GeneratorConfiguration conf) throws IOException {
        File generateConfFile = new File(FilenameUtils.concat(System.getProperty("user.home"), ".generator/generator-config.properties"));
        if(!generateConfFile.exists()) {
            FileUtils.forceMkdir(generateConfFile.getParentFile());
            generateConfFile.createNewFile();
        }

        String content = Files.toString(generateConfFile, Charset.forName(conf.getEncoding()));
        int startIndex = content.indexOf("db.url=");
        int endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "db.url=" + conf.getDbUrl() + "\n";
        } else {
            content = content.substring(0, startIndex + "db.url=".length()) + conf.getDbUrl() + content.substring(endIndex);
        }

        startIndex = content.indexOf("db.username=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "db.username=" + conf.getDbUsername() + "\n";
        } else {
            content = content.substring(0, startIndex + "db.username=".length()) + conf.getDbUsername() + content.substring(endIndex);
        }

        startIndex = content.indexOf("db.password=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "db.password=" + conf.getDbPassword() + "\n";
        } else {
            content = content.substring(0, startIndex + "db.password=".length()) + conf.getDbPassword() + content.substring(endIndex);
        }

        startIndex = content.indexOf("root.project.name=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "root.project.name=" + conf.getProjectName() + "\n";
        } else {
            content = content.substring(0, startIndex + "root.project.name=".length()) + conf.getProjectName() + content.substring(endIndex);
        }

        startIndex = content.indexOf("dbType=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "dbType=" + conf.getDbType() + "\n";
        } else {
            content = content.substring(0, startIndex + "dbType=".length()) + conf.getDbType() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.persistence.type=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.persistence.type=" + conf.getPersistenceType() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.persistence.type=".length()) + conf.getPersistenceType() + content.substring(endIndex);
        }

        startIndex = content.indexOf("root.project.directory=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "root.project.directory=" + conf.getRootProjectDirectory() + "\n";
        } else {
            content = content.substring(0, startIndex + "root.project.directory=".length()) + conf.getRootProjectDirectory() + content.substring(endIndex);
        }

        startIndex = content.indexOf("base.package.name=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "base.package.name=" + conf.getBasePackage() + "\n";
        } else {
            content = content.substring(0, startIndex + "base.package.name=".length()) + conf.getBasePackage() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.encoding=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.encoding=" + conf.getEncoding() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.encoding=".length()) + conf.getEncoding() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.domain=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.domain=" + conf.isGenerateDomain() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.domain=".length()) + conf.isGenerateDomain() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.dao=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.dao=" + conf.isGenerateDao() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.dao=".length()) + conf.isGenerateDao() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.sqlmap=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.sqlmap=" + conf.isGenerateSqlMap() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.sqlmap=".length()) + conf.isGenerateSqlMap() + content.substring(endIndex);
        }

        startIndex = content.indexOf("exclude.columns=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "exclude.columns=" + StringUtils.join(conf.getExcludeColumns(), conf.getSplitChar()) + "\n";
        } else {
            content = content.substring(0, startIndex + "exclude.columns=".length()) + StringUtils.join(conf.getExcludeColumns(), conf.getSplitChar()) + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useMysql=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useMysql=" + conf.isUseMysql() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useMysql=".length()) + conf.isUseMysql() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useOracle=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useOracle=" + conf.isUseOracle() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useOracle=".length()) + conf.isUseOracle() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useRedis=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useRedis=" + conf.isUseRedis() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useRedis=".length()) + conf.isUseRedis() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useSafServer=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useSafServer=" + conf.isUseSafServer() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useSafServer=".length()) + conf.isUseSafServer() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useSafClient=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useSafClient=" + conf.isUseSafClient() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useSafClient=".length()) + conf.isUseSafClient() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useZookeeper=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useZookeeper=" + conf.isUseZookeeper() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useZookeeper=".length()) + conf.isUseZookeeper() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useMQ=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useMQ=" + conf.isUseMQ() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useMQ=".length()) + conf.isUseMQ() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.needBaseUser=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.needBaseUser=" + conf.isNeedBaseUser() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.needBaseUser=".length()) + conf.isNeedBaseUser() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useRpcModule=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useRpcModule=" + conf.isUseRpcModule() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useRpcModule=".length()) + conf.isUseRpcModule() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useIsRpcModule=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useIsRpcModule=" + conf.isUseIsRpcModule() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useIsRpcModule=".length()) + conf.isUseIsRpcModule() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.useWorkModule=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.useWorkModule=" + conf.isUseWorkModule() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.useWorkModule=".length()) + conf.isUseWorkModule() + content.substring(endIndex);
        }

        Files.write(content, generateConfFile, Charset.forName(conf.getEncoding()));
        this.saveUserCustomConfig(conf.getSelectTableInfoList());
    }

    public void saveUserCustomConfig(List<TableInfo> tableInfoList) throws IOException {
        if(tableInfoList != null) {
            Iterator var3 = tableInfoList.iterator();

            while(var3.hasNext()) {
                TableInfo tableInfo = (TableInfo)var3.next();
                this.saveUserCustomConfig(tableInfo);
            }
        }

    }

    protected void saveUserCustomConfig(TableInfo tableInfo) throws IOException {
        File generateConfFile = new File(FilenameUtils.concat(System.getProperty("user.home"), ".generator/tables/" + tableInfo.getTableName()));
        if(!generateConfFile.exists()) {
            FileUtils.forceMkdir(generateConfFile.getParentFile());
            generateConfFile.createNewFile();
        }

        String content = Files.toString(generateConfFile, Charset.forName("UTF-8"));
        int startIndex = content.indexOf("generate.domain=");
        int endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.domain=" + tableInfo.isGenerateDomain() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.domain=".length()) + tableInfo.isGenerateDomain() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.dao=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.dao=" + tableInfo.isGenerateDao() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.dao=".length()) + tableInfo.isGenerateDao() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.sqlmap=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.sqlmap=" + tableInfo.isGenerateSqlMap() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.sqlmap=".length()) + tableInfo.isGenerateSqlMap() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.manager=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.manager=" + tableInfo.isGenerateManager() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.manager=".length()) + tableInfo.isGenerateManager() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.service=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.service=" + tableInfo.isGenerateService() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.service=".length()) + tableInfo.isGenerateService() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.controller=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.controller=" + tableInfo.isGenerateController() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.controller=".length()) + tableInfo.isGenerateController() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.create=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.create=" + tableInfo.isGenerateCreate() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.create=".length()) + tableInfo.isGenerateCreate() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.update=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.update=" + tableInfo.isGenerateUpdate() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.update=".length()) + tableInfo.isGenerateUpdate() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.delete=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.delete=" + tableInfo.isGenerateDelete() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.delete=".length()) + tableInfo.isGenerateDelete() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.query=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.query=" + tableInfo.isGenerateQuery() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.query=".length()) + tableInfo.isGenerateQuery() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.on.exists.override=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.on.exists.override=" + tableInfo.isOnExistsOverride() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.on.exists.override=".length()) + tableInfo.isOnExistsOverride() + content.substring(endIndex);
        }

        startIndex = content.indexOf("generate.needSharding=");
        endIndex = content.indexOf("\n", startIndex);
        if(startIndex == -1) {
            content = content + "generate.needSharding=" + tableInfo.isNeedSharding() + "\n";
        } else {
            content = content.substring(0, startIndex + "generate.needSharding=".length()) + tableInfo.isNeedSharding() + content.substring(endIndex);
        }

        Files.write(content, generateConfFile, Charset.forName("UTF-8"));
    }

    public Map<String, Object> buildRootForTemplete(GeneratorConfiguration daoConfiguration, TableInfo tableInfo) {
        HashMap root = new HashMap();
        root.put("baseCommonEntityPackage", daoConfiguration.getBaseCommonEntityPackage());
        root.put("basePackage", daoConfiguration.getBasePackage());
        root.put("projectName", daoConfiguration.getProjectName());
        root.put("entityPackage", daoConfiguration.getDomainPackage());
        root.put("daoPackage", daoConfiguration.getDaoPackage());
        root.put("daoImpPackage", daoConfiguration.getDaoImplPackage());
        root.put("commonPackage", daoConfiguration.getCommonPackage());
        root.put("servicePackage", daoConfiguration.getServicePackage());
        root.put("serviceImpPackage", daoConfiguration.getServiceImplPackage());
        root.put("managerPackage", daoConfiguration.getManagerPackage());
        root.put("managerImpPackage", daoConfiguration.getManagerImplPackage());
        root.put("controllerPackage", daoConfiguration.getControllerPackage());
        root.put("encoding", StringUtils.trimToEmpty(daoConfiguration.getEncoding()));
        if(tableInfo != null) {
            String className = TransformUtils.getTablesNameToClassName(tableInfo.getTableName());
            String lowerName = className.substring(0, 1).toLowerCase() + className.substring(1, className.length());
            root.put("className", className);
            root.put("lowerName", lowerName);
            root.put("codeName", StringUtils.trimToEmpty(tableInfo.getTableComment()));
            root.put("tableName", tableInfo.getTableName());
            root.put("tableNameUpper", tableInfo.getTableName().toUpperCase());
            root.put("tablesAsName", TransformUtils.getTablesASName(tableInfo.getTableName()));
            root.put("columnDatas", tableInfo.getColumnDataList());
            root.put("columnKeyDatas", tableInfo.getColumnKeyDataList());
            root.put("columnKeyParam", TransformUtils.getColumnKeyParam(tableInfo.getColumnKeyDataList()));
            root.put("columnKeyParamValue", TransformUtils.getColumnKeyParamValue(tableInfo.getColumnKeyDataList(), ","));
            root.put("columnKeyParamValuePrint", TransformUtils.getColumnKeyParamValuePrint(tableInfo.getColumnKeyDataList()));
            root.put("columnKeySort", TransformUtils.getColumnKeySort(tableInfo.getColumnKeyDataList()));
            root.put("beanFieldDataTypes", tableInfo.getBeanFieldDataTypeSet());
        }

        return root;
    }

    public Configuration buildFreemarkerConfiguration(GeneratorConfiguration conf) {
        Configuration configuration = new Configuration();
        String templateBasePath = "/" + conf.getDbType() + "/" + conf.getPersistenceType() + "/ftl";
        configuration.setClassForTemplateLoading(this.getClass(), templateBasePath);
        configuration.setObjectWrapper(new DefaultObjectWrapper());
        return configuration;
    }
}

